/*
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
*/
package uk.co.gidley.teamAlert.alertServices;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.gidley.teamAlert.listenerServices.AlertListener;
import uk.co.gidley.teamAlert.vo.Alert;
import uk.co.gidley.teamAlert.vo.AlertType;

import java.io.IOException;
import java.security.SecureRandom;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA. User: ben Date: Jun 17, 2008 Time: 7:19:06 AM
 */
public class NazabtagAlert implements AlertListener {
	private final Logger logger = LoggerFactory.getLogger(NazabtagAlert.class);

	private String baseUrl;
	private String token;
	private String serialNumber;
	private static final String PARAM_SERIAL = "sn";
	private static final String PARAM_TOKEN = "token";
	private static final String PARAM_TEXT = "tts";
	private HttpClient httpClient;
	private List<String> goodMessages;

	private List<String> globalSucessBuildTunes;
	private List<String> globalFailBuildTunes;
	private Map<String, List> personalBuildTunes;
	private SecureRandom secureRandom = new SecureRandom();
	private static final String PARAM_IDMESSAGE = "idmessage";

	public NazabtagAlert() {
		httpClient = new HttpClient();

	}

	public String getBaseUrl() {
		return baseUrl;
	}

	public void setBaseUrl(String baseUrl) {
		this.baseUrl = baseUrl;
	}

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getSerialNumber() {
		return serialNumber;
	}

	public void setSerialNumber(String serialNumber) {
		this.serialNumber = serialNumber;
	}

	public void onAlert(Alert alert) {
		sendGlobalBuildTune(alert);
		sendPersonalBuildTunes(alert);
		sendTTSSegment(alert);
	}

	private void sendPersonalBuildTunes(Alert alert) {
		for (String key : personalBuildTunes.keySet()) {
			if (alert.getBuildMessage().contains(key)) {
				sendMp3Segment(personalBuildTunes.get(key));
			}
		}

	}

	private void sendGlobalBuildTune(Alert alert) {
		if (alert.getType().equals(AlertType.FIXED)) {
			sendMp3Segment(globalSucessBuildTunes);
		} else {
			sendMp3Segment(globalFailBuildTunes);
		}
	}

	/**
	 * From list of tunes pick one at random and play it
	 *
	 * @param list
	 */
	private void sendMp3Segment(List list) {
		String mp3Key = (String) list.get(secureRandom.nextInt(list.size()));
		PostMethod method = createPost();
		method.addParameter(PARAM_IDMESSAGE, mp3Key);
		sendMessage(method);
	}


	private void sendTTSSegment(Alert alert) {
		PostMethod method = createPost();
		method.addParameter(PARAM_TEXT, alert.getShortMessage());
		method.addParameter("chor", "10,0,motor,1,20,0,0, 0,led,2,0,238,0,2,led,1,250,0,0,3,led,2,0,0,0");
		sendMessage(method);
	}

	private PostMethod createPost() {
		PostMethod method = new PostMethod(baseUrl);
		method.addParameter(PARAM_SERIAL, serialNumber);
		method.addParameter(PARAM_TOKEN, token);
		return method;
	}

	private void sendMessage(PostMethod method) {
		try {

			httpClient.executeMethod(method);

			if (method.getStatusCode() != 200) {
				logger.error("HTTP error sending to Rabbit: {}", method.getResponseBodyAsString());
			} else {
				SAXReader reader = new SAXReader();
				Document doc = reader.read(method.getResponseBodyAsStream());
				String message = doc.valueOf("/rsp/message[1]");
				String comment = doc.valueOf("/rsp/comment[1]");

				if (!goodMessages.contains(message)) {
					logger.error("Failed Response Message: {}", message);
					logger.error("Failed Comment Message: {}", comment);
				} else {
					logger.debug("Response Message: {}", message);
					logger.debug("Comment Message: {}", comment);
				}
			}
		} catch (IOException e) {
			logger.error("Failed to send alert", e);
		} catch (DocumentException e) {
			logger.error("Failed parsing response", e);
		} finally {
			method.releaseConnection();
		}
	}

	public List<String> getGoodMessages() {
		return goodMessages;
	}

	public void setGoodMessages(List<String> goodMessages) {
		this.goodMessages = goodMessages;
	}

	public Map<String, List> getPersonalBuildTunes() {
		return personalBuildTunes;
	}

	public void setPersonalBuildTunes(Map<String, List> personalBuildTunes) {
		this.personalBuildTunes = personalBuildTunes;
	}

	public List<String> getGlobalSuccessBuildTunes() {
		return globalSucessBuildTunes;
	}

	public void setGlobalSuccessBuildTunes(List<String> globalBuildTunes) {
		this.globalSucessBuildTunes = globalBuildTunes;
	}

	public List<String> getGlobalFailBuildTunes() {
		return globalFailBuildTunes;
	}

	public void setGlobalFailBuildTunes(List<String> globalFailBuildTunes) {
		this.globalFailBuildTunes = globalFailBuildTunes;
	}
}
